package com.yunhe.device.service.base.impl;

import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.filter.ServerContext;
import com.yunhe.common.filter.ServerContextHolder;
import com.yunhe.common.util.CollectionUtil;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.StringUtil;
import com.yunhe.device.domain.base.PointDataType;
import com.yunhe.device.domain.base.DeviceType;
import com.yunhe.device.model.base.AnlogTypeQueryCondition;
import com.yunhe.device.model.base.AnlogTypeVo;
import com.yunhe.device.model.base.StatusVo;
import com.yunhe.device.repository.base.AnalogTypeRepository;
import com.yunhe.device.repository.base.impl.AnlogTypeDao;
import com.yunhe.device.service.base.AnlogTypeService;
import com.yunhe.device.utils.BeansUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yunhe.common.util.CollectionUtil;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName AnlogTypeServiceImpl
 * @Description TODO
 * @Author HeTao
 * @Date 2021/7/13 17:47
 * @Version 1.0
 **/
@Service
public class AnlogTypeServiceImpl implements AnlogTypeService {

    @Autowired
    private AnalogTypeRepository analogTypeRepository;

    @Autowired
    private AnlogTypeDao anlogTypeDao;

    /**
     * 校验编码 名称是否重复
     * @param anlogType
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     * @throws ObjectNotFoundException
     */
    private void processBeforeSave(PointDataType anlogType)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        //判断点号数据类型代码、编号、标题是否为空
        if (StringUtil.isEmpty(anlogType.getName())
                || StringUtil.isEmpty(anlogType.getTitle())) {
            throw new ArgumentErrorException("点号类型编码、标题不能为空");
        }
        //判断代码是否已存在
        PointDataType typeByName = this.findByName(anlogType.getName());
        if (typeByName != null) {
            if (anlogType.getId() == null || typeByName.getId().longValue() != anlogType.getId().longValue()) {
                throw new UniqueConstraintsException("该点号类型编码已存在");
            }
        }
        //判断编号是否已存在
        PointDataType typeByTitle = this.findByTitle(anlogType.getTitle());
        if (typeByTitle != null) {
            if (anlogType.getId() == null || typeByTitle.getId().longValue() != anlogType.getId().longValue()) {
                throw new UniqueConstraintsException("该点号类型名称已存在");
            }
        }
    }

    private PointDataType findByTitle(String title) {
        return analogTypeRepository.findByTitle(title);
    }

    private PointDataType findByName(String name) {
        return analogTypeRepository.findByName(name);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public PointDataType createAnlogType(PointDataType anlogType) throws ObjectNotFoundException, UniqueConstraintsException, ArgumentErrorException {
        anlogType.setId(null);
        String format = DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date());
        anlogType.setSn(DateTimeUtils.getTimestamp(format,null));
        anlogType.setCreateTime(format);
        anlogType.setInitData(true);
        processBeforeSave(anlogType);
        return analogTypeRepository.save(anlogType);
    }

    @Override
    public Iterable<AnlogTypeVo> getAnlogTypeByCondition(AnlogTypeQueryCondition anlogTypeQueryCondition) {
        Iterable<AnlogTypeVo> results = null;
        Page<PointDataType> anlogTypes = null;
        Pageable pageable = PageRequest.of(anlogTypeQueryCondition.getPage()-1, anlogTypeQueryCondition.getSize());
        anlogTypes = anlogTypeDao.getAnlogTypeByCondition(anlogTypeQueryCondition);
        if(anlogTypes != null){
            List<PointDataType> content = anlogTypes.getContent();
            List<AnlogTypeVo> anlogTypeVos = BeansUtil.listCopy(content, AnlogTypeVo.class);
            results = new PageImpl(anlogTypeVos,pageable,anlogTypes.getTotalElements());
        }
        return results;
    }

    @Override
    public AnlogTypeVo getAnlogTypeById(Long id) throws ObjectNotFoundException {
        AnlogTypeVo reuslt = new AnlogTypeVo();
        PointDataType anlogType = analogTypeRepository.findById(id).orElse(null);
        if(anlogType == null){
            throw new ObjectNotFoundException("无此点号类型信息");
        }
        BeanUtils.copyProperties(anlogType,reuslt);
        return reuslt;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void deleteAnlogTypeById(Long id) throws ArgumentErrorException, ObjectNotFoundException {
        AnlogTypeVo anlogTypeById = getAnlogTypeById(id);
        if(anlogTypeById == null){
            throw new ObjectNotFoundException("无此点号类型信息");
        }
        //查询当前点号类型是否绑定设备类型如果绑定 不能删除
        List<DeviceType> equipmentTypes = analogTypeRepository.findAnlogTypeById(id);
        if(!CollectionUtil.isEmpty(equipmentTypes)){
            throw new ArgumentErrorException("点号类型："+anlogTypeById.getTitle()+"已与相关设备类型绑定，不能删除！");
        }
        analogTypeRepository.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public PointDataType updateAnlogType(PointDataType anlogType) throws ObjectNotFoundException, UniqueConstraintsException, ArgumentErrorException {
        PointDataType anlogTypeById = analogTypeRepository.findById(anlogType.getId()).orElse(null);
        if(anlogTypeById == null){
            throw new ObjectNotFoundException("找不到对应点号类型");
        }
        anlogTypeById.setActivity(anlogType.getActivity());
        anlogTypeById.setUpdateTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date()));
        anlogTypeById.setTitle(anlogType.getTitle());
        anlogTypeById.setType(anlogType.getType());
        processBeforeSave(anlogTypeById);
        PointDataType newAnlogType = analogTypeRepository.save(anlogTypeById);
        return newAnlogType;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void updateAnlogTypeStatus(StatusVo statusVo) throws ObjectNotFoundException, UniqueConstraintsException, ArgumentErrorException {
        List<Long> ids = statusVo.getIds();
        for (Long id : ids) {
            PointDataType anlogTypeById = analogTypeRepository.findById(id).orElse(null);
            if(anlogTypeById == null){
                throw new ObjectNotFoundException("找不到对应点号类型");
            }
            anlogTypeById.setActivity(statusVo.getActivity());
            anlogTypeById.setUpdateTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date()));
            processBeforeSave(anlogTypeById);
            PointDataType newAnlogType = analogTypeRepository.save(anlogTypeById);
        }
    }

    @Override
    public Iterable<PointDataType> getAnlogTypeByEquipTypeName(String equipName) {
        //return anlogTypeDao.findByEquipTypeName(equipName,page,size);
        if(StringUtil.isEmpty(equipName)){
            return analogTypeRepository.findByActivityAndBackType("1","01");
        }else {
            String projectCode = ServerContextHolder.getContext().getProjectCode();
            return  analogTypeRepository.getAnlogTypeByEquipTypeName(equipName,Long.valueOf(projectCode));
        }
    }

    @Override
    public Iterable<AnlogTypeVo> getAnlogTypeByEquipTypeId(Long id, int page, int size) {
        Iterable<AnlogTypeVo> results = null;
        Page<PointDataType> anlogTypes = null;
        Pageable pageable = PageRequest.of(page-1, size);
        anlogTypes = analogTypeRepository.getAnlogTypeByEquipTypeId(id,pageable);
        if(anlogTypes != null){
            List<PointDataType> content = anlogTypes.getContent();
            List<AnlogTypeVo> anlogTypeVos = BeansUtil.listCopy(content, AnlogTypeVo.class);
            results = new PageImpl(anlogTypeVos,pageable,anlogTypes.getTotalElements());
        }
        return results;
    }

    @Override
    public List<AnlogTypeVo> getAnlogTypeByEquipTypeId(Long id) {
        List<AnlogTypeVo> anlogTypeVos = new ArrayList<>();
        List<PointDataType> anlogTypes = analogTypeRepository.getAnlogTypesByEquipTypeId(id);
        if(!CollectionUtil.isEmpty(anlogTypes)) {
            anlogTypeVos = BeansUtil.listCopy(anlogTypes, AnlogTypeVo.class);
        }
        return anlogTypeVos;
    }


}
